package org.rbac.action;

import java.awt.Color;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;


import org.apache.log4j.Logger;
import org.json.JSONArray;
import org.json.JSONObject;
import org.patchca.color.ColorFactory;
import org.patchca.color.SingleColorFactory;
import org.patchca.filter.predefined.CurvesRippleFilterFactory;
import org.patchca.filter.predefined.DiffuseRippleFilterFactory;
import org.patchca.filter.predefined.DoubleRippleFilterFactory;
import org.patchca.filter.predefined.MarbleRippleFilterFactory;
import org.patchca.filter.predefined.WobbleRippleFilterFactory;
import org.patchca.service.ConfigurableCaptchaService;
import org.patchca.utils.encoder.EncoderHelper;
import org.patchca.word.RandomWordFactory;
import org.rbac.content.define.RbacKeyDefine;
import org.rbac.content.define.RbacKeyDefine.keys;
import org.rbac.serv.UserServices;
import org.rbac.util.UserUtil;
import org.rbac.vo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.kingschan.encrypt.DesEncrypt;
import com.kingschan.web.CookieUtil;

/**
 * 索引控制器,主页和登录跳转
 * 
 * <pre>
 * 项目名称：rbac
 * 类名称：IndexAction
 * 类描述：索引控制器,主页和登录跳转
 * 创建人：唐家林(tjl)
 * 创建时间：2014-9-25 下午4:46:51
 * 修改人：
 * 修改时间：
 * 修改备注：
 * @version
 * </pre>
 */
@Controller
public class IndexAction {

    private Logger log = Logger.getLogger(IndexAction.class);
	@Autowired
	private UserServices userServ;

	private static final String cookie_user_name_key="cookie_user_name_key";
	private static final String cookie_user_psw_key="cookie_user_psw_key";
	private static final String cookie_user_CommomEncrypt_key="kingschan_rbac";
	@Value("${rbac.admins}")
	private String admins;
	
	
	public String getAdmins() {
        return admins;
    }
    /**
	 * 登录
	 * 
	 * @param req
	 *            HTTP请求对象实例
	 * @param rep
	 *            HTTP响应对象实例
	 * @return 返回跳转路径模型
	 * @throws UnsupportedEncodingException 
	 */
	@RequestMapping(value = "/signin")
	public String signIn(HttpServletRequest req, HttpServletResponse rep,Boolean isRemember,
	                           String account,
	                           String password,
	                           String vcode
	                           ) throws UnsupportedEncodingException {
		int is_success=0;
		boolean remember=(null==isRemember)?false:isRemember;
		User u =(User) req.getSession().getAttribute(RbacKeyDefine.getKey(keys.CURRENT_USER));
		if (null!=u) {
            log.info(String.format("用户[%s]已经登录！", u.getUAlias()));
            is_success=1;
        }else{
            CookieUtil cu = new CookieUtil(req,rep);
            Cookie[] cookies=cu.getCookies();
            if (null!=cookies&&cookies.length!=0) {
                //cookie 存在
                log.info("cookie 存在");
                String username=cu.getCookieAttribute(IndexAction.cookie_user_name_key);
                String psw=cu.getCookieAttribute(IndexAction.cookie_user_psw_key);
                DesEncrypt des = DesEncrypt.getInstance(IndexAction.cookie_user_CommomEncrypt_key);
                if (null!=psw&&!psw.isEmpty()) {
                   psw=des.getDesString(psw);
                }
               if (null!=username&&null!=psw) {
                   log.info("使用cookie记忆登录");
                   is_success=login(req, rep, des.getDesString(username), psw, remember,null,false);
                   if (is_success!=1) {                    
                       clearLoginCookies(req,rep);  
                    log.info("cookie 信息错误，清除cookie!");
                   }
               }else{
                   log.info("存在的cookie信息不完整，改成正常表单登录模式！");
                   is_success=login(req, rep, account, password, remember,vcode,true); 
               }
            }else{
                //不存在cookie
                is_success=login(req, rep, account, password, remember,vcode,true);
            }
        }
		if (is_success==-1) {
            req.setAttribute("msg", "帐号或密码错误!");
        }else if (is_success==-2) {
            req.setAttribute("msg", "验证码错误!");
        }else if(is_success==1){
        	//登录成功后，设置默认登录系统为rbac
        	HttpSession session = req.getSession(true);
        	session.setAttribute("current_system", "tms");
        }
		
		return is_success==1?"redirect:main.do":"/rbac/login";
	}
        /**
         * 1正常   -1帐号密码错误  0第一将次进入  -2 验证码错误 
         * @param req
         * @param rep
         * @param account
         * @param password
         * @param isRemember
         * @return
         * @throws UnsupportedEncodingException
         */
	int login(HttpServletRequest req, HttpServletResponse rep,String account,String password,Boolean isRemember,String vcode,boolean enable_vcode) throws UnsupportedEncodingException{
	    if(null==account||null==password||account.isEmpty()||password.isEmpty()){
	        log.info("第一次进入，表单信息为空!");
	        return 0;
	    }
	    if (enable_vcode) {
            if (null==vcode||vcode.isEmpty()||!vcode.equals(req.getSession().getAttribute("vcode"))) {
                return -2;
            }
        }
	    User user = userServ.login(account, password);
	    if (null==user) {return -1; }
	    if (isRemember) {
	        CookieUtil cu = new CookieUtil(req,rep);
	        DesEncrypt des = DesEncrypt.getInstance(IndexAction.cookie_user_CommomEncrypt_key);
	        cu.setCookieAttribute(cookie_user_name_key,des.getEncString(account), 60*60*24*3);
	        cu.setCookieAttribute(cookie_user_psw_key, des.getEncString(password), 60*60*24*3);
	        log.info("将帐号密码记录到cookie里面有效期为3天");
        }
        /* 获得用户所有权限资源 */
        List<Map<String, Object>> lis = userServ.userAuthority(req, user.getId());
        // URL资源
        Map<String, Object> urlAction = new HashMap<String, Object>();
        // 按钮资源
        String key = null;
        List<Object> btnLis = null;
        Map<String, List<Object>> btnAction = new HashMap<String, List<Object>>();
        for (Map<String, Object> map : lis) {
            //0URL 1按钮 2菜单
            if (1 == (Integer.parseInt(map.get("a_type").toString()))) { // 按钮
                key = String.valueOf(map.get("pa_url"));
                btnLis = btnAction.get(key);
                if (null == btnLis) {
                    btnLis = new ArrayList<Object>();
                    btnLis.add(map);
                    btnAction.put(key, btnLis);
                } else {
                    btnLis.add(map);
                }
            } else { // URL
                urlAction.put(String.valueOf(map.get("a_url")), map);
            }
        }
        user.setAdmin(getAdmins().indexOf(String.format("%s;", user.getUAccount()))!=-1);
        req.getSession().setAttribute(RbacKeyDefine.getKey(keys.CURRENT_USER), user);
        // 按钮权限
        req.getSession().setAttribute(RbacKeyDefine.getKey(keys.USER_BTN_AUTHORITY_KEY), btnAction);
        // URL权限
        req.getSession().setAttribute(RbacKeyDefine.getKey(keys.USER_URL_AUTHORITY_KEY), urlAction);
        return 1;
	}
	/**
	 * 清理掉记录的登录信息
	 * @param req
	 * @param res
	 */
	public void clearLoginCookies(HttpServletRequest req,HttpServletResponse res){
	    CookieUtil cu = new CookieUtil(req, res);
        cu.removeCookie(cookie_user_name_key);
        cu.removeCookie(cookie_user_psw_key);
	}
	
	/**
	 * 没有权限跳转页面
	 * @return
	 */
	@RequestMapping("/withoutPrivilege")
	public String withoutPrivilege(){
        return "/rbac/withoutPrivilege";
	    
	}
	
	
	/**
	 * 退出登录
	 * 
	 * @param request
	 *            HTTP请求对象实例
	 */
	@RequestMapping(value = "/logoff")
	public String logoff(HttpServletRequest request,HttpServletResponse res) {
		UserUtil.loginOut(request);
		clearLoginCookies(request,res);		
		return "redirect:/signin.do";
	}

	/**
	 * 主框架
	 * 
	 * @param req
	 *            HTTP请求对象实例
	 * @param rep
	 *            HTTP响应对象实例
	 * @return 返回跳转路径模型
	 */
	@RequestMapping(value = "/main")
	public ModelAndView main() {
		ModelAndView mav = new ModelAndView();
		mav.setViewName("/rbac/main");
		return mav;
	}
	private static ConfigurableCaptchaService cs = null;
    private static ColorFactory cf = null;
    private static RandomWordFactory wf = null;
    private static Random r = new Random();
    private static CurvesRippleFilterFactory crff = null;//干扰线波纹  
    private static MarbleRippleFilterFactory mrff = null;//大理石波纹  
    private static DoubleRippleFilterFactory drff = null;//双波纹 
    private static WobbleRippleFilterFactory wrff = null;//摆波纹  
    private static DiffuseRippleFilterFactory dirff = null;//漫波纹     
    @RequestMapping(value = "/vcode")
    public void vcode(HttpServletRequest request, HttpServletResponse response) throws IOException {
        cs = new ConfigurableCaptchaService();
        cf = new SingleColorFactory(new Color(25, 60, 170));
        wf = new RandomWordFactory();
        crff = new CurvesRippleFilterFactory(cs.getColorFactory());
        drff = new DoubleRippleFilterFactory();
        wrff = new WobbleRippleFilterFactory();
        dirff = new DiffuseRippleFilterFactory();
        mrff = new MarbleRippleFilterFactory();
        cs.setWordFactory(wf);
        cs.setColorFactory(cf);
        
        response.setContentType("image/png");
        response.setHeader("cache", "no-cache");
        wf.setMaxLength(4);
        wf.setMinLength(4);
        cs.setWidth(110);
        cs.setHeight(40);

        HttpSession session = request.getSession(true);
        OutputStream os = response.getOutputStream();
        switch (r.nextInt(5))
        {
        case 0:
          cs.setFilterFactory(crff);
          break;
        case 1:
          cs.setFilterFactory(mrff);
          break;
        case 2:
          cs.setFilterFactory(drff);
          break;
        case 3:
          cs.setFilterFactory(wrff);
          break;
        case 4:
          cs.setFilterFactory(dirff);
        }
//        cs.setFilterFactory(crff);
        String captcha = EncoderHelper.getChallangeAndWriteImage(cs, "png", os);
        System.out.println("生成的验证码是：" + captcha);
        session.setAttribute("vcode", captcha);
        os.flush();
        os.close();
    }
    
    /**
     * @查询系统列表
     * @param req
     * @param system
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value="/systemChange")
    public String updateAppMapping(HttpServletRequest req,String system) throws Exception{
	    String flag="true";
       try {
    	   HttpSession session = req.getSession(true);
    	   System.out.println(session.getId()+":"+system);
    	   session.setAttribute("current_system", system);
        } catch (Exception e) {
            e.printStackTrace();
            flag="false";
        }
        return flag;
    }
    
    /**
     * @查询用户所有资源
     * @param req
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value="/queryUserRes")
    public String queryUserRes(HttpServletRequest req) throws Exception{
	    List<Map> list = new ArrayList<Map>();
	    String result = "";
	    JSONArray jsonArray = new JSONArray();
       try {
    	   User user = (User)req.getSession().getAttribute("Current_User");
    	   list = userServ.queryUserRes(user.getId());
    	   for (Map map : list) {
    		   JSONObject jsonObject = new JSONObject(map);
    		   jsonArray.put(jsonObject);
    	   }
    	   result = jsonArray.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
}
